<template>
  <div ref="chartContainer" class="three-d-point-chart-container"></div>
</template>

<script setup lang="ts">
import { ref, onMounted, onUnmounted, watch, nextTick, computed } from 'vue';
// 先导入echarts-gl再导入echarts，确保3D功能优先加载
import 'echarts-gl';
import * as echarts from 'echarts';
import { formatSampletime } from "@/utils/appCommon/timeUtil";

// 定义设备数据类型 - 支持3D散点
interface DeviceData {
  deviceId: string;
  deviceName: string;
  data: Array<{ x: number; y: number; z: number }>;
  color?: string;
}

// 定义组件 props - 包含3D相关配置
const props = defineProps<{
  title: string;
  xAxisField: string;
  xAxisUnit: string;
  yAxisField: string;
  yAxisUnit: string;
  zAxisField: string;
  zAxisUnit: string;
  devicesData: DeviceData[];
  showToolbar?: boolean;
  autoRangePadding?: number;
  symbolSize?: number;
  showPointLabel?: boolean;
}>();

// 定义组件 emits
const emit = defineEmits<{
  (e: 'point-click', params: {
    deviceName: string;
    deviceId?: string;
    x: number;
    y: number;
    z: number;
  }): void
}>();

// 图表容器引用
const chartContainer = ref<HTMLDivElement | null>(null);
// 图表实例引用
let chartInstance: echarts.ECharts | null = null;

// 预定义的颜色数组 - 使用高对比度颜色
const defaultColors = [
  '#ff0000', '#00ff00', '#0000ff', '#ffff00', '#ff00ff',
  '#00ffff', '#ff6600', '#9900ff', '#ff0099', '#0099ff'
];

// 计算所有数据的x轴范围
const xAxisRange = computed(() => {
  const allXValues: number[] = [];
  props.devicesData.forEach(device => {
    device.data.forEach(point => {
      if (point.x !== null && point.x !== undefined && !isNaN(Number(point.x))) {
        allXValues.push(Number(point.x));
      }
    });
  });

  if (allXValues.length === 0) return { min: 0, max: 100 };

  const min = Math.min(...allXValues);
  const max = Math.max(...allXValues);
  const range = max - min || 100; // 避免除以零

  // 添加适当的内边距
  const padding = range * (props.autoRangePadding || 0.1);
  return {
    min: min - padding,
    max: max + padding
  };
});

// 计算所有数据的y轴范围
const yAxisRange = computed(() => {
  const allYValues: number[] = [];
  props.devicesData.forEach(device => {
    device.data.forEach(point => {
      if (point.y !== null && point.y !== undefined && !isNaN(Number(point.y))) {
        allYValues.push(Number(point.y));
      }
    });
  });

  if (allYValues.length === 0) return { min: 0, max: 100 };

  const min = Math.min(...allYValues);
  const max = Math.max(...allYValues);
  const range = max - min || 100; // 避免除以零

  // 添加适当的内边距
  const padding = range * (props.autoRangePadding || 0.1);
  return {
    min: min - padding,
    max: max + padding
  };
});

// 计算所有数据的z轴范围
const zAxisRange = computed(() => {
  const allZValues: number[] = [];
  props.devicesData.forEach(device => {
    device.data.forEach(point => {
      if (point.z !== null && point.z !== undefined && !isNaN(Number(point.z))) {
        allZValues.push(Number(point.z));
      }
    });
  });

  if (allZValues.length === 0) return { min: 0, max: 100 };

  const min = Math.min(...allZValues);
  const max = Math.max(...allZValues);
  const range = max - min || 100; // 避免除以零

  // 添加适当的内边距
  const padding = range * (props.autoRangePadding || 0.1);
  return {
    min: min - padding,
    max: max + padding
  };
});

// 获取设备的颜色
const getDeviceColor = (device: DeviceData, index: number): string => {
  if (device.color) {
    return device.color;
  }
  return defaultColors[index % defaultColors.length];
};

// 窗口大小变化处理函数
const handleResize = () => {
  if (chartInstance) {
    chartInstance.resize();
  }
};

// 检查3D支持函数
const check3DSupport = (): boolean => {
  try {
    // 测试3D功能是否可用
    const testChart = echarts.init(document.createElement('div'));
    const testOption = {
      grid3D: {},
      xAxis3D: { type: 'value' },
      yAxis3D: { type: 'value' },
      zAxis3D: { type: 'value' },
      series: [{ type: 'scatter3D', data: [] }]
    };
    testChart.setOption(testOption);
    testChart.dispose();
    return true;
  } catch (e) {
    console.warn('3D support not available:', e);
    return false;
  }
};

// 初始化图表
const initChart = () => {
  if (!chartContainer.value) {
    console.warn('Chart container not found');
    return;
  }

  // 销毁现有实例
  if (chartInstance) {
    chartInstance.dispose();
  }

  try {
    // 创建新实例
    chartInstance = echarts.init(chartContainer.value);
    console.log('3D Chart instance created successfully');

    // 检查3D支持
    const has3DSupport = check3DSupport();
    console.log('has3DSupport:', has3DSupport);

    // 准备系列数据 - 参考官方demo的结构
    const allData: any[] = [];
    const dataMap: Map<number, {deviceName: string, deviceId?: string}> = new Map();

    let pointIndex = 0;
    props.devicesData.forEach((device, deviceIndex) => {
      const deviceColor = getDeviceColor(device, deviceIndex);

      // 过滤并转换有效的数据点
      device.data.forEach(point => {
        if (point.x !== null && point.x !== undefined && !isNaN(Number(point.x)) &&
            point.y !== null && point.y !== undefined && !isNaN(Number(point.y)) &&
            point.z !== null && point.z !== undefined && !isNaN(Number(point.z))) {

          // 添加数据点并保存设备信息映射
          allData.push([
            Number(point.x),
            Number(point.y),
            Number(point.z),
            pointIndex // 用于识别数据点
          ]);
          dataMap.set(pointIndex, {deviceName: device.deviceName, deviceId: device.deviceId});
          pointIndex++;
        }
      });
    });

    console.log(`Total valid data points: ${allData.length}`);
    console.log('Data sample:', allData.slice(0, 3));

    // 创建单个系列（参考官方demo）
    const series = [{
      name: props.title || '三维散点图',
      type: 'scatter3D',
      // 明确指定维度
      dimensions: ['x', 'y', 'z', 'index'],
      data: allData,
      symbolSize: props.symbolSize || 12,
      itemStyle: {
        color: '#1710c0', // 默认颜色
        opacity: 1,
        borderWidth: 1,
        borderColor: 'rgba(255,255,255,0.8)'
      },
      emphasis: {
        itemStyle: {
          color: '#fff'
        }
      }
    }];

    // 图表配置选项 - 参考官方demo结构
    const option: any = {
      title: {
        text: props.title || '三维散点图',
        left: 'center',
        textStyle: {
          color: '#333',
          fontSize: 16
        }
      },
      tooltip: {
        trigger: 'item',
        formatter: (params: any) => {
          if (!params || !params.value) return '';

          const xValue = params.value[0];
          let xDisplay = xValue;
          const pointInfo = dataMap.get(params.value[3]);

          // 处理时间戳
          if (props.xAxisField === 'sampletime') {
            try {
              xDisplay = formatSampletime(xValue);
            } catch (e) {
              console.warn('Failed to format sampletime:', e);
            }
          }

          return `
            ${pointInfo ? pointInfo.deviceName : '未知设备'}<br/>
            X: ${xDisplay}${!props.xAxisField.includes('sampletime') && props.xAxisUnit ? ` ${props.xAxisUnit}` : ''}<br/>
            Y: ${params.value[1]}${props.yAxisUnit ? ` ${props.yAxisUnit}` : ''}<br/>
            Z: ${params.value[2]}${props.zAxisUnit ? ` ${props.zAxisUnit}` : ''}
          `;
        }
      },
      grid3D: {
        // 简化grid3D配置，参考官方demo
        axisLine: {
          lineStyle: {
            color: '#333'
          }
        },
        axisPointer: {
          lineStyle: {
            color: '#ffbd67'
          }
        },
        viewControl: {
          // 设置固定视角以便更好地查看数据
          autoRotate: true,
          autoRotateSpeed: 10,
          // 禁用2D风格的缩放和平移，但保留3D缩放
          panMouseButton: 'right',
          zoomOnMouseWheel: true,
          rotateMouseButton: 'left'
        }
      },
      xAxis3D: {
        type: 'value',
        name: props.xAxisField || 'X轴',
        nameLocation: 'middle',
        nameGap: 30,
        // min: xAxisRange.value.min,
        // max: xAxisRange.value.max,
        // 调整轴样式以避免圆柱状显示
        axisLine: {
          show: true,
          lineStyle: {
            color: '#333',
            width: 1
          }
        },
        splitLine: {
          show: true,
          lineStyle: {
            color: '#666',
            type: 'dashed',
            width: 1
          }
        },
        axisLabel: {
          show: true,
          color: '#333',
          fontSize: 12
        }
      },
      yAxis3D: {
        type: 'value',
        name: props.yAxisField || 'Y轴',
        nameLocation: 'middle',
        nameGap: 40,
        min: yAxisRange.value.min,
        max: yAxisRange.value.max,
        axisLine: {
          lineStyle: {
            color: '#333',
            width: 2
          }
        },
        splitLine: {
          show: true,
          lineStyle: {
            color: '#666',
            type: 'dashed',
            width: 1
          }
        },
        axisLabel: {
          show: true,
          color: '#333',
          fontSize: 12
        }
      },
      zAxis3D: {
        type: 'value',
        name: props.zAxisField || 'Z轴',
        nameLocation: 'middle',
        nameGap: 30,
        min: zAxisRange.value.min,
        max: zAxisRange.value.max,
        axisLine: {
          lineStyle: {
            color: '#333',
            width: 2
          }
        },
        splitLine: {
          show: true,
          lineStyle: {
            color: '#666',
            type: 'dashed',
            width: 1
          }
        },
        axisLabel: {
          show: true,
          color: '#333',
          fontSize: 12
        }
      },
      series: series,
      toolbox: props.showToolbar !== false ? {
        feature: {
          saveAsImage: {
            title: '保存图片',
            pixelRatio: 2
          },
          restore: {
            title: '还原'
          }
        },
        right: 10
      } : undefined,
      // 错误监听
      animation: true
    };

    console.log('Setting chart option with:', {
      seriesCount: series.length,
      totalDataPoints: series.reduce((sum, s) => sum + s.data.length, 0),
      xRange: xAxisRange.value,
      yRange: yAxisRange.value,
      zRange: zAxisRange.value
    });

    // 设置配置项
    chartInstance.setOption(option);

    // 监听渲染完成事件
    chartInstance.on('finished', () => {
      console.log('3D Chart rendered successfully');
    });

    // 监听错误事件
    chartInstance.on('error', (error: any) => {
      console.error('3D Chart rendering error:', error);
    });

    // 绑定点击事件
    chartInstance.off('click');
    chartInstance.on('click', (params: any) => {
      console.log('Point clicked:', params);
      if (params.componentType === 'series' && params.data && Array.isArray(params.data)) {
        const pointInfo = dataMap.get(params.data[3]);
        if (pointInfo) {
          emit('point-click', {
            deviceName: pointInfo.deviceName,
            deviceId: pointInfo.deviceId,
            x: Number(params.data[0]),
            y: Number(params.data[1]),
            z: Number(params.data[2])
          });
        }
      }
    });
  } catch (error) {
    console.error('Error initializing 3D chart:', error);
    // 显示错误信息
    if (chartContainer.value) {
      chartContainer.value.innerHTML = `<div style="text-align: center; padding: 50px; color: red;">
        3D图表初始化失败: ${error instanceof Error ? error.message : '未知错误'}
      </div>`;
    }
  }
};

// 监听数据变化
watch(() => props.devicesData, () => {
  console.log('Devices data changed, updating chart');
  nextTick(() => {
    initChart();
  });
}, { deep: true });

// 监听其他重要属性变化
watch([
  () => props.title,
  () => props.xAxisUnit,
  () => props.yAxisUnit,
  () => props.zAxisUnit,
  () => props.symbolSize
], () => {
  if (chartInstance) {
    initChart();
  }
});

// 组件挂载
onMounted(() => {
  nextTick(() => {
    // 确保容器有足够高度
    if (chartContainer.value) {
      if (!chartContainer.value.style.height) {
        chartContainer.value.style.height = '500px';
      }
    }
    initChart();
    window.addEventListener('resize', handleResize);
  });
});

// 组件卸载
onUnmounted(() => {
  if (chartInstance) {
    chartInstance.dispose();
    chartInstance = null;
  }
  window.removeEventListener('resize', handleResize);
});
</script>

<style scoped lang="scss">
.three-d-point-chart-container {
  width: 100%;
  height: 100%;
  min-height: 500px; // 增加最小高度以便更好地查看3D效果
  box-sizing: border-box;
  background-color: #f5f5f5; // 设置背景色增加对比度
}

// 自定义tooltip样式
:deep(.echarts-tooltip) {
  border-radius: 4px;
  border: 1px solid #ddd;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
  padding: 8px;
  background-color: rgba(255, 255, 255, 0.95);
  font-size: 12px;
}
</style>
